/**
 * @file 通用右键菜单预加载脚本
 * @description 为渲染进程提供通用的右键菜单功能，支持自定义菜单项和回调处理
 * @author 黄敏
 * @version 1.0.0
 * @since 2025-07-03
 */

import type {
  ContextMenuItem,
  ContextMenuItemWithFn as CtxItemWithFn,
  MenuDisplayOptions
} from '~shared/types/context-menu'

// @ts-ignore

import { contextMenuTopic } from '~shared/ipc-topic'

const electron = require('electron')

/**
 * 菜单项接口定义
 */

/**
 * 设置回调监听器
 * @param menuItems - 菜单项数组
 * @param callbackId - 回调ID
 */
function setupCallbackListeners(menuItems: CtxItemWithFn[], callbackId: string): void {
  for (const [index, item] of menuItems.entries()) {
    if (item.click) {
      const callbackEventName = `${contextMenuTopic.callback}-${callbackId}-${index}`

      const handler = () => {
        // 立即移除监听器，避免重复触发
        electron.ipcRenderer.removeListener(callbackEventName, handler)

        // 执行回调
        try {
          item.click?.()
        } catch (error) {
          console.error(`[ContextMenu] 回调执行失败:`, error)
        }
      }

      electron.ipcRenderer.on(callbackEventName, handler)
    }

    // 递归处理子菜单
    if (item.submenu) {
      setupCallbackListeners(item.submenu, `${callbackId}-${index}`)
    }
  }
}

/**
 * 处理菜单项用于传输到主进程（移除不能序列化的函数）
 * @param menuItems - 原始菜单项数组
 * @returns 处理后的菜单项数组
 */
function processMenuItemsForTransfer(menuItems: CtxItemWithFn[]): ContextMenuItem[] {
  return menuItems.map(item => {
    const { click: _click, submenu, ...rest } = item
    const processedItem: ContextMenuItem = { ...(rest as ContextMenuItem) }

    // 递归处理子菜单
    if (submenu) {
      processedItem.submenu = processMenuItemsForTransfer(submenu)
    }

    return processedItem
  })
}

/**
 * 清理回调监听器
 * @param menuItems - 菜单项数组
 * @param callbackId - 回调ID
 */
function cleanupCallbackListeners(menuItems: CtxItemWithFn[], callbackId: string): void {
  for (const [index, item] of menuItems.entries()) {
    if (item.click) {
      const callbackEventName = `${contextMenuTopic.callback}-${callbackId}-${index}`
      electron.ipcRenderer.removeAllListeners(callbackEventName)
    }

    // 递归清理子菜单监听器
    if (item.submenu) {
      cleanupCallbackListeners(item.submenu, `${callbackId}-${index}`)
    }
  }
}

/**
 * 通用右键菜单API对象
 */
export const contextMenu = {
  /**
   * 显示右键菜单
   * @param menuItems - 菜单项配置数组
   * @param options - 可选配置
   * @returns Promise<void>
   */
  show: (menuItems: CtxItemWithFn[], options?: MenuDisplayOptions): Promise<void> => {
    return new Promise<void>((resolve, reject) => {
      try {
        // 生成唯一的回调ID
        const callbackId = `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`

        // 设置回调监听器
        setupCallbackListeners(menuItems, callbackId)

        // 监听菜单关闭事件，延迟清理避免竞态条件
        const closeEventName = `${contextMenuTopic.closed}-${callbackId}`
        const closeHandler = () => {
          // 延迟清理，确保回调有足够时间执行
          setTimeout(() => {
            cleanupCallbackListeners(menuItems, callbackId)
            resolve()
          }, 100)
        }

        electron.ipcRenderer.once(closeEventName, closeHandler)

        // 处理菜单项用于传输（移除不可序列化的函数）
        const processedMenuItems = processMenuItemsForTransfer(menuItems)

        // 发送显示菜单请求到主进程
        electron.ipcRenderer.send(contextMenuTopic.show, {
          menuItems: processedMenuItems,
          callbackId,
          options
        })
      } catch (error) {
        reject(error)
      }
    })
  }
}

/**
 * 全局右键菜单对象
 * @description 在渲染进程中可用的通用右键菜单API
 *
 * @example
 * ```typescript
 * // 显示简单的右键菜单
 * _pre_.contextMenu.show([
 *   { label: '复制', click: () => console.log('复制') },
 *   { type: 'separator' },
 *   { label: '粘贴', click: () => console.log('粘贴') }
 * ])
 *
 * // 显示带图标和子菜单的右键菜单
 * _pre_.contextMenu.show([
 *   {
 *     label: '编辑',
 *     submenu: [
 *       { label: '剪切', click: () => console.log('剪切') },
 *       { label: '复制', click: () => console.log('复制') },
 *       { label: '粘贴', click: () => console.log('粘贴') }
 *     ]
 *   },
 *   { type: 'separator' },
 *   { label: '删除', click: () => console.log('删除') }
 * ])
 * ```
 */
